﻿Imports System.IO
Imports System.Text

Imports System.Text.RegularExpressions


Public Class ExportVBP


    Private PathOfProject As String
    Private FullNameFileOfProject As String = "D:\sviluppo\projects\vb6\iatrosXp\xpPanorama\Panorama.vbp"
    Private maxDepth As Short = 0 'profondità relativa del percoso del progetto
    Private rows() As String 'immagazzina le righe del file da scansire
    Private newRowsVBP() As String 'immagazzina le righe del file vbp modificato con percorso relativo
    Private BASEVBP As String = "" 'contiene il nuovo file modificato con percorsi assoluti
    Private nch As noCloneHelper.csv

    Private CloneA As New List(Of noCloneHelper.csv)
    Private CloneB As New List(Of noCloneHelper.csv)

    Private vsh As VisualStudioHelper.vbp




#Region "eventi dell'UI"
    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        Button1.Enabled = False

        'impostazioni salvate dal programma
        tbCopyCommand.Text = My.Settings.copyCommand
        tbProjectSelected.Text = My.Settings.lastProjectSelected
        validateProjectFile()

    End Sub

    ''' <summary>
    ''' selezione della sorgente
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub Button2_Click_1(sender As System.Object, e As System.EventArgs) Handles Button2.Click
        'apro il file del progetto da elaborare

        Dim ofd As New OpenFileDialog
        ofd.InitialDirectory = "D:\sviluppo\"
        If ofd.ShowDialog() = Windows.Forms.DialogResult.OK Then

            FullNameFileOfProject = ofd.FileName
            tbProjectSelected.Text = FullNameFileOfProject
            Button1.Enabled = True

            My.Settings.lastProjectSelected = FullNameFileOfProject
        End If


    End Sub

    ''' <summary>
    ''' Seleziona la destinazione ed esporta
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click

        Button1.Enabled = False


        'Dim ffd As New OpenFileDialog
        'ffd.InitialDirectory = New FileInfo(FullNameFileOfProject).DirectoryName
        'ffd.FileName = New FileInfo(FullNameFileOfProject).Name

        'If ffd.ShowDialog() Then

        Me.Cursor = Cursors.WaitCursor
        'analizzo il file in entrata e inizializzo le prime variabili utili
        Dim fi As New FileInfo(FullNameFileOfProject)
        PathOfProject = fi.DirectoryName()

        'recupero i percorsi dei files
        Dim percorsi() As String = PrendiPercorsi()

        Me.Cursor = Cursors.Default

        'End If

    End Sub
    Private Sub Button4_Click(sender As System.Object, e As System.EventArgs) Handles Button4.Click
        'Analizzo il file di Noclone
        Dim ofd As New OpenFileDialog
        If ofd.ShowDialog() = Windows.Forms.DialogResult.OK Then

            tbNoCloneCSV.Text = ofd.FileName

            'apro il file e controllo i percorsi inseriti
            Dim sr As New StreamReader(tbNoCloneCSV.Text)
            'questa linea non mi interessa
            sr.ReadLine()


            Do While sr.Peek

                Dim tmp As String = sr.ReadLine()
                Dim atmp As String() = tmp.Split(",")
                Dim a As New noCloneHelper.csv(atmp(0), atmp(1), atmp(2))
                CloneA.Add(a)


                tmp = sr.ReadLine()
                atmp = tmp.Split(",")
                Dim b As New noCloneHelper.csv(atmp(0), atmp(1), atmp(2))
                CloneB.Add(b)


                noCloneHelper.csv.percorsoVBP = "c:\export\naz\"

            Loop

        End If

    End Sub

    Private Sub Button3_Click(sender As System.Object, e As System.EventArgs) Handles Button3.Click
        'apro il file e controllo i percorsi inseriti
        Dim sr As New StreamReader(tbNoCloneCSV.Text)
        Dim percorsoBASEdelVBP As String = "C:\export"




    End Sub

    Private Sub Button7_Click(sender As System.Object, e As System.EventArgs) Handles Button7.Click
        Dim ofd As New OpenFileDialog
        If ofd.ShowDialog() = Windows.Forms.DialogResult.OK Then
            tbNoCloneCSV.Text = ofd.FileName
        End If

    End Sub

    Private Sub Button5_Click(sender As System.Object, e As System.EventArgs) Handles Button5.Click
        Dim ofd As New OpenFileDialog
        If ofd.ShowDialog() = Windows.Forms.DialogResult.OK Then
            tbPrjPrincipale.Text = ofd.FileName
        End If
    End Sub

    Private Sub Button6_Click(sender As System.Object, e As System.EventArgs) Handles Button6.Click
        Dim ofd As New OpenFileDialog
        If ofd.ShowDialog() = Windows.Forms.DialogResult.OK Then
            tbPrjSecondario.Text = ofd.FileName
        End If
    End Sub

    Private Sub Button8_Click(sender As System.Object, e As System.EventArgs) Handles Button8.Click
        Dim fbd As New FolderBrowserDialog
        If fbd.ShowDialog() = Windows.Forms.DialogResult.OK Then
            tbPrjCommon.Text = fbd.SelectedPath
        End If
    End Sub

    Private Sub tbProjectSelected_Leave(sender As Object, e As System.EventArgs) Handles tbProjectSelected.Leave
        validateProjectFile()
        Debug.Print("leave mmm")
    End Sub

    Private Sub tbProjectSelected_Validating(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles tbProjectSelected.Validating
        validateProjectFile()
        Debug.Print("validating mmm")

    End Sub

#End Region

    Private Sub validateProjectFile()
        If File.Exists(tbProjectSelected.Text) Then
            FullNameFileOfProject = tbProjectSelected.Text
            errProv.Clear()
            Button1.Enabled = True
        Else
            errProv.SetError(tbProjectSelected, "Progetto non valido o inesistente")
            Button1.Enabled = False

        End If
    End Sub

    ''' <summary>
    ''' Procedura principale
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function PrendiPercorsi() As String()
        Dim dest As String = "C:\export"
        Dim fdialog As New SaveFileDialog
        fdialog.InitialDirectory = dest

        fdialog.FileName = FullNameFileOfProject.Substring(0, FullNameFileOfProject.Length - 3) & "bat"

        If fdialog.ShowDialog() = Windows.Forms.DialogResult.OK Then
            dest = New FileInfo(fdialog.FileName).DirectoryName
            Dim sr As New StreamReader(FullNameFileOfProject)
            Dim AbsoluteRowsPercorso(100) As String
            Dim origRowsPercorso(100) As String
            Array.Resize(rows, 100)

            Dim desPaths() As String

            'check preferenza
            Dim subfolder As String = ""
            If cbSubfolder.Checked And tbNomeSubFolder.Text <> "" Then
                subfolder = tbNomeSubFolder.Text
            End If

            Dim i As Integer = 0    'conta le righe con percorsi da modificare
            Dim j As Integer = 0    'conta le righe totali
            Dim fi As New FileInfo(FullNameFileOfProject)


            Dim FileNameBat As String = Path.Combine(dest, fi.Name.Substring(0, fi.Name.Length - fi.Extension.Length) & ".bat")

            FileNameBat = fdialog.FileName

            Dim FileNameVBPDest As String = Path.Combine(dest, fi.Name)
            'dest = New FileInfo(saveBatName).Directory.ToString
            vsh = New VisualStudioHelper.vbp

            'Preanalisi: determino il maxdepth ciclando su tutte le righe del documento che metto in memoria in rows()
            Do Until sr.Peek < 0
                rows(j) = sr.ReadLine()

                'If i >= 100 Then Array.Resize(AbsoluteRowsPercorso, i + 1)

                If rows(j).IndexOf("Module") = 0 Or rows(j).IndexOf("Class") = 0 Then
                    RelativeToAbsolutePath(RicavaPercorsoFromRow(rows(j), vsh.GetRegQForKeyModule()))
                ElseIf rows(j).IndexOf("Form") = 0 Or rows(j).IndexOf("UserControl") = 0 Then
                    RelativeToAbsolutePath(RicavaPercorsoFromRow(rows(j), vsh.GetRegQForKeyForm()))
                End If

                j += 1
                If j >= 100 Then Array.Resize(rows, j + 1)

            Loop
            sr.Close()

            Array.Resize(newRowsVBP, j)

            'immagazzino la lunghezza del percorso assoluto da LeftTrimmare
            'TODO: 1 se flg attivo si può trimmare il percorso comune ed aggiungere
            '       poi il percorso della nuova sottocartella di progetto
            Dim r As Short = Len(cutPath(AbsoluteRowsPercorso(0), maxDepth))

            'passaggio 2: elaboro il vbp con l'array di rows()
            Dim tmp As Integer = j
            j = 0
            Do While j < tmp

                If i >= 100 Then
                    Array.Resize(AbsoluteRowsPercorso, i + 1)
                    Array.Resize(origRowsPercorso, i + 1)
                End If

                If rows(j).IndexOf("Module") = 0 Or rows(j).IndexOf("Class") = 0 Then
                    origRowsPercorso(i) = RicavaPercorsoFromRow(rows(j), vsh.GetRegQForKeyModule())


                    AbsoluteRowsPercorso(i) = RelativeToAbsolutePath(origRowsPercorso(i))
                    newRowsVBP(j) = rows(j).Replace(origRowsPercorso(i), Path.Combine(subfolder, AbsoluteRowsPercorso(i).Substring(r + 1)))
                    i += 1


                ElseIf rows(j).IndexOf("Form") = 0 Or rows(j).IndexOf("UserControl") = 0 Then
                    origRowsPercorso(i) = RicavaPercorsoFromRow(rows(j), vsh.GetRegQForKeyForm())


                    AbsoluteRowsPercorso(i) = RelativeToAbsolutePath(origRowsPercorso(i))
                    newRowsVBP(j) = rows(j).Replace(origRowsPercorso(i), Path.Combine(subfolder, AbsoluteRowsPercorso(i).Substring(r + 1)))
                    i += 1
                    'If rows(j).IndexOf("Form") = 0 Then
                    '    'devo ricordarmi di portare via anche il file .frx

                    'End If

                Else
                    'le altre righe non le tocco, ma possono contenere info utili come le librerie varie collegate al progetto
                    newRowsVBP(j) = rows(j)

                End If



                j += 1
            Loop

            Debug.Print("Per mettere il progetto alla base è necessario aggiornare i percorsi per un salto di " & CStr(maxDepth) & " cartelle")
            'ora ho un array pieno di percorsi

            Array.Resize(desPaths, AbsoluteRowsPercorso.Length)



            Dim sw As TextWriter
            sw = My.Computer.FileSystem.OpenTextFileWriter(FileNameBat, False, New ASCIIEncoding)

            For j = 0 To i - 1
                Dim p As String = AbsoluteRowsPercorso(j).Substring(r + 1)

                desPaths(j) = Path.Combine(dest, Path.Combine(subfolder, p))
                sw.WriteLine("mkdir " & Path.Combine(New FileInfo(desPaths(j)).DirectoryName, subfolder))
                sw.WriteLine("copy " & AbsoluteRowsPercorso(j) & " " & desPaths(j))
                If AbsoluteRowsPercorso(j).IndexOf(".frm") = AbsoluteRowsPercorso(j).Length - 4 Then
                    sw.WriteLine("copy " & AbsoluteRowsPercorso(j).Substring(0, AbsoluteRowsPercorso(j).Length - 1) & "x " & desPaths(j).Substring(0, desPaths(j).Length - 1) & "x")
                End If
            Next

            sw.Close()

            sw = My.Computer.FileSystem.OpenTextFileWriter(FileNameVBPDest, False, New ASCIIEncoding)
            For Each s As String In newRowsVBP
                sw.WriteLine(s)
            Next
            sw.Close()

            'creazione delle sottocartelle
            '(vengono fatte dal bat)

            'posso portarli tutti allo stesso livello in modo da mettere il progetto alla base del percorso:
        End If

    End Function


    ''' <summary>
    ''' Restituisce il fullName della cartella precedente depth volte, al percorso indicato in original
    ''' </summary>
    ''' <param name="original"></param>
    ''' <param name="depth"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function cutPath(original, depth) As String

        Dim i As Integer

        Dim fi As New FileInfo(FullNameFileOfProject)
        Dim di As New DirectoryInfo(fi.DirectoryName)

        For i = 0 To depth - 1
            di = di.Parent
        Next

        Return di.FullName


    End Function

    ''' <summary>
    ''' Esegue la regex per ottenere il valore del percorso del file da analizzare
    ''' </summary>
    ''' <param name="row"></param>
    ''' <param name="regQuery"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function RicavaPercorsoFromRow(row As String, regQuery As String) As String

        Dim re As New Regex(regQuery)
        If re.IsMatch(row) Then
            Return re.Match(row).Groups("percorso").Value
        End If

        Return ""

    End Function

    ''' <summary>
    ''' in base al PathOfProject valorizzato esternamente, calcola il percorso assoluto di ogni file
    ''' </summary>
    ''' <param name="percorso"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function RelativeToAbsolutePath(percorso As String) As String
        Dim regQuery As String = "\.\.\\"
        Dim relpathCount As Short = 0
        Dim fi As New FileInfo(PathOfProject)
        Dim fld As New DirectoryInfo(PathOfProject)
        Dim ftmp As DirectoryInfo = fld

        Dim re As New Regex(regQuery)
        Dim m As Match = re.Match(percorso)
        Do While m.Success
            relpathCount += 1
            ftmp = ftmp.Parent
            m = m.NextMatch
        Loop

        maxDepth = IIf(maxDepth > relpathCount, maxDepth, relpathCount)

        Return Path.Combine(ftmp.FullName, percorso.Substring(3 * relpathCount))


    End Function






End Class

'#Region "Regex"

' ''' <summary>
' ''' Trasforma una riga che inizia con Module in una riga batch
' ''' </summary>
' ''' <returns></returns>
' ''' <remarks></remarks>
'Private Function GetRegQForKeyModule() As String
'    'esempio:
'    'Module=BtrApi32; ..\..\pervasive\BtrApi32.bas
'    'Class=API_Directory; class\API_Directory.cls
'    Return "(Module|Class)=.+;\s+(?<percorso>.+)"

'End Function

'Private Function GetRegQForKeyForm() As String
'    'esempio:
'    'Form=UI\frmFarma.frm
'    'UserControl=UI\userControls\myButton.ctl
'    Return "(UserControl|Form)=(?<percorso>.+)"
'End Function

'#End Region